package cn.felord.security.cloud.oauth2.resource.server.autoconfigure;

import cn.felord.security.cloud.oauth2.resource.server.autoconfigure.handler.SimpleAccessDeniedHandler;
import cn.felord.security.cloud.oauth2.resource.server.autoconfigure.handler.SimpleAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

import java.util.Collections;
import java.util.List;

/**
 * OAuth2.0 资源服务器配置
 */
@Configuration(proxyBeanMethods = false)
public class OAuth2ResourceServerConfiguration {
    private List<HttpSecurityCustomizer> httpSecurityCustomizers = Collections.emptyList();

    /**
     * Jwt security filter chain security filter chain.
     *
     * @param httpSecurity the http
     * @return the security filter chain
     * @throws Exception the exception
     */
    @Bean
    SecurityFilterChain jwtSecurityFilterChain(HttpSecurity httpSecurity) throws Exception {
        HttpSecurity http = httpSecurity.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests(request -> request.anyRequest()
                        .access("@checkerBean.check(authentication,request)"))
                .exceptionHandling()
                .accessDeniedHandler(new SimpleAccessDeniedHandler())
                .authenticationEntryPoint(new SimpleAuthenticationEntryPoint())
                .and()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
        httpSecurityCustomizers
                .forEach(httpSecurityCustomizer -> httpSecurityCustomizer.customize(http));
        return http
                .build();
    }

    @Autowired(required = false)
    void setWebSecurityCustomizers(List<HttpSecurityCustomizer> httpSecurityCustomizers) {
        this.httpSecurityCustomizers = httpSecurityCustomizers;
    }
}
